package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.HuanXin.HuanXinTemplate;
import com.itheima.autoconfig.face.AipFaceTemplate;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.autoconfig.sms.SmsTemplate;
import com.itheima.domain.db.Log;
import com.itheima.domain.db.User;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.vo.ErrorResult;
import com.itheima.domain.vo.UserInfoVo;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import com.itheimma.service.db.UserInfoService;
import com.itheimma.service.db.UserService;
import com.oracle.xmlns.internal.webservices.jaxws_databinding.JavaWsdlMappingType;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.lang.reflect.Type;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Component
public class UserManager {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @DubboReference
    private UserService userService;

    @DubboReference
    private UserInfoService userInfoService;
    //sms发送短信模板
    @Autowired
    private SmsTemplate smsTemplate;

    @Autowired
    private AipFaceTemplate aipFaceTemplate;

    @Autowired
    private OssTemplate ossTemplate;
    //Redis的调用

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private HuanXinTemplate huanXinTemplate;


    public ResponseEntity save(User user){
        Long userId = userService.save(user);
        return ResponseEntity.ok(userId);   //响应状态码，并把响应结果放进响应体中返回
    }

    public ResponseEntity findByPhone(String phone){
        User user = userService.findByPhone(phone);
        try{
           int i = 1/0;
        }catch (Exception e){
            e.printStackTrace();
            return ResponseEntity.status(500).body(ErrorResult.error());
        }
        return ResponseEntity.ok(user);
    }

    public void sendSms(String phone){
        //验证码即为动态密码，由系统给发配
        //1、先设置一个6位数的验证码，
        //2、利用sms把验证码发送
        //3、把手机号和验证码存入Redis,并设置时间为5分钟

        String smsCode = RandomUtil.randomNumbers(6);
        //TODO 方便测试
        smsCode = "123456";

        //TODO 上线时放开 smsTemplate.sendSms(phone,smsCode);

        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE+phone , smsCode, Duration.ofMinutes(5));
    }

    //登入和注册
    public ResponseEntity regAndLogin(String phone , String verificationCode){
        //1、和Redis中的验证码比较
        //2、和数据库中查询该手机号，若没有该手机号则为新用户，认为为注册，保存该用户信息
        //3、为用户信息制作token，将token存入redis
        //4、将用户的token和新用户或老用户的身份返回，返回的是新老用户来返回不同的页面

        String smsCode = stringRedisTemplate.opsForValue().get(ConstantUtil.SMS_CODE + phone);

        if (!StrUtil.equals(smsCode,verificationCode)){
            return ResponseEntity.status(500).body(ErrorResult.loginError());
        }

        //定义类型
        String type ;

        User user = userService.findByPhone(phone);
        boolean isNew;
        if (user == null){
            isNew = true;
            user = new User();
            user.setPhone(phone);
            user.setPassword("123456");
            Long ID = userService.save(user);   //返回的是主键id，例110L
            user.setId(ID);

            //向环信注册用户
            huanXinTemplate.register(ID);

            type = "0102"; //新用户，注册
        }else{
            isNew = false;

            type = "0101";  //老用户，登入
        }

        user.setPassword(null); //抹除密码信息
        Map<String, Object> claims = BeanUtil.beanToMap(user);
        String token = JwtUtil.createToken(claims); //token只是作为一个key来用
        String json = JSON.toJSONString(user);//json作为一个值在传入，存储的是用户的信息

        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token ,json, Duration.ofDays(7));

        //发送日志消息
        //1-1 准备消息
        Log log = new Log();
        log.setUserId(user.getId()); // 操作人id
        log.setLogTime(DateUtil.formatDate(new Date())); // 操作时间
        log.setPlace("三里屯"); // 操作地点
        log.setEquipment("大华为"); //操作设备
        log.setType(type); // 操作类型

        //1-2 发送消息
        rocketMQTemplate.convertAndSend("tanhua-log",log);

        //返回结果
        HashMap<String, Object> map = new HashMap<>();
        map.put("isNew",isNew);
        map.put("token",token);

        return ResponseEntity.ok(map);
    }

    //完善用户信息 TODO 测一下
    public void saveUserInfoBase(UserInfo userInfo , String token){
        //1、根据用户信息查询userID
        //2、把userId存进userInfo
        //3、把userInfo存进数据库
        User user = findByToken(token);
        userInfo.setId(user.getId());
        userInfoService.save(userInfo);


    }

    //完善用户头像信息 TODO 测一下
    public ResponseEntity saveUserInfoHead(MultipartFile headPhoto ,String token) throws IOException {
        //1、从token获取userID
        //2、把headPhoto使用AIp检查
        //3、检查通过保存到OSS，获取url
        //4、把url保存到userInfo
        //5、userInfo保存到数据库
        User user = findByToken(token);
        boolean bool = aipFaceTemplate.detect(headPhoto.getBytes());
        if (! bool){
            return ResponseEntity.status(500).body(ErrorResult.faceError());
        }

        String url = ossTemplate.upload( headPhoto.getOriginalFilename(), headPhoto.getInputStream());

        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId());
        userInfo.setCoverPic(url);//封面
        userInfo.setAvatar(url);//头像
        userInfoService.update(userInfo);

        return ResponseEntity.ok(null);
    }

    //查询用户细信息
    public ResponseEntity findUserInfoVo(Long userId){
        //1、根据用户id查询用户信息
        //2、将userInfo转换为vo，并传回去
        //3、单独设置age
        UserInfo userInfo = userInfoService.findById(userId);
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtil.copyProperties(userInfo,userInfoVo);
        if (userInfo.getAge() != null){
            userInfoVo.setAge(userInfo.getAge().toString());
        }

        return ResponseEntity.ok(userInfoVo);
    }

    //更新信息
    public void updateUserInfoBase(UserInfo userInfo ){
        //User user = findByToken(token);
        User user = UserHolder.get();

        userInfo.setId(user.getId());

        userInfoService.update(userInfo);
    }


    //抽取，根据token获取User
    public User findByToken(String token){
        //1、从redis中取出user的json格式
        String json = stringRedisTemplate.opsForValue().get(ConstantUtil.USER_TOKEN + token);

        //2、判断json是否为空，空则返回null
        if (StrUtil.isEmpty(json)){
            return null;
        }
        //3、有值则转化为user对象
        User user = JSON.parseObject(json, User.class);

        //TODO 实验
     /*   try {
            Map map = JwtUtil.parseToken(token);
            User u1 = BeanUtil.mapToBean(map, User.class, true);
            System.out.println(u1);
        }catch (Exception e){
            e.printStackTrace();
        }
*/

        //4、存储redis更新7天
        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token,json,Duration.ofDays(7));

        return user;
    }
}
